package com.MutiModule.common.utils.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

import com.MutiModule.common.utils.JSONUtilss;
import com.MutiModule.common.utils.StringUtilss;

public class FileDatabaseHelper {
	
    public boolean isFileCreateSuccessful = true;
    private File file;
    private BufferedWriter writer;
    private FileWriter fileWriter;
    private BufferedReader reader;
    private FileReader fileReader;
    
    public FileDatabaseHelper(String filePath, String fileName) {
    	if(filePath == null) {
    		file = new File(fileName);
    	} else {
    		//文件夹初始化
    		File _file = new File(filePath);
    		_file.mkdirs();
    		
    		file = new File(filePath + File.separator + fileName);
    	}
    	
    	if(file.exists() == false){
    		try {
    			file.createNewFile();
    		} catch (IOException e) {
    			e.printStackTrace();
    			isFileCreateSuccessful = false;
    			System.out.println("Database initialize fail");
    		}
    	}
	}

    public boolean addData(String data){
        if(dataCheck(data) == false) return false;

        try {
            initWriter();
            writer.write(data.toString());
            writer.newLine();
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }finally {
            try {
                writer.close();
                fileWriter.close();
            }catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    public boolean updateData(String id,String data){
        if(dataCheck(data) == false) return false;
        if(deleteData(id)){
            addData(data);
            return true;
        }
        return false;
    }

    public boolean deleteData(String id){
        int lineNumber = findDataById(id);
        if(lineNumber != -1){
            deleteDataByLineNumber(lineNumber);
            return true;
        }
        return false;
    }

    private boolean dataCheck(String data){
        if(isFileCreateSuccessful == false){
            System.out.println("Database doesn't exist, insert fail");
            return false;
        }
        if(StringUtilss.isEmpty(data)){
            System.out.println("Record is not complete, insert fail");
            return false;
        }
        return true;
    }

    private boolean  initWriter(){
    	
        try {
            writer = new BufferedWriter(fileWriter =new FileWriter(file,true));
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private boolean  initReader(){
        try {
            reader = new BufferedReader(fileReader = new FileReader(file));
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private int findDataById(String id){
        initReader();
        String tmpStr;
        boolean isFind =false;
        int lineNumber = -1;
        int currentLineNumber =0;
        try {
            initReader();
            while ((tmpStr = reader.readLine()) != null && isFind == false){
            	BaseFileDatabaseEntity baseFileDatabaseEntity = JSONUtilss.readValue(tmpStr, BaseFileDatabaseEntity.class, true);
            	if(baseFileDatabaseEntity.getId().longValue() == Long.parseLong(id)) {
            		lineNumber = currentLineNumber;
            		isFind = true;
            	}
                currentLineNumber++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {

            try {
                reader.close();
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  lineNumber;
    }
    
    public <T> T selectEntityById(String id, Class<T> valueType) {
    	initReader();
        String tmpStr;
        boolean isFind =false;
        T _returnEntity = null;
        try {
            initReader();
            while ((tmpStr = reader.readLine()) != null && isFind == false){
            	T t = JSONUtilss.readValue(tmpStr, valueType, true);
            	BaseFileDatabaseEntity baseFileDatabaseEntity = (BaseFileDatabaseEntity)t;
            	if(baseFileDatabaseEntity.getId().equals(id)) { 
            		_returnEntity = t;
            		isFind = true;
            	}
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {

            try {
                reader.close();
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  _returnEntity;
    }

    private boolean deleteDataByLineNumber(int lineNumber){
        List<String> lines = new ArrayList<>();
        RandomAccessFile oldFile = null,newFile = null;

        try {
            oldFile = new RandomAccessFile(file,"r");
            newFile = new RandomAccessFile(file,"rw");
            oldFile.seek(0);
            String tmpStr;
            while((tmpStr = oldFile.readLine()) != null){
                lines.add(tmpStr);
            }
            new FileOutputStream(file, false);
            newFile.seek(0);
            lines.remove(lineNumber);
            for(int i =0 ; i<lines.size();i++){
                newFile.writeBytes(lines.get(i));
                newFile.writeBytes(System.getProperty("line.separator"));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }finally {
            try {
                oldFile.close();
                newFile.close();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }
    
    public List<String> selectAllData() {
    	List<String> returnStrList = new ArrayList<String>();
    	
    	int currentLineNumber =-1;
        try {
            initReader();
            String tmpStr;
            while ((tmpStr = reader.readLine()) != null){
            	returnStrList.add(tmpStr);
                currentLineNumber++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                reader.close();
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(currentLineNumber == -1){
            System.out.println("Database has no data");
        }
        return returnStrList;
    }

    public void printAllData(){
        int currentLineNumber =-1;
        try {
            initReader();
            String tmpStr;
            while ((tmpStr = reader.readLine()) != null){
                System.out.println(tmpStr);
                currentLineNumber++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {

            try {
                reader.close();
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(currentLineNumber == -1){
            System.out.println("Database has no data");
        }
    }

}